using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using System.Linq.Expressions;
using System.Linq;

using PACKETPARSERMAX20.CORE;

namespace PACKETPARSERMAX20.WinUI
{
    public partial class frmLogList : DockContent
    {
        public frmLogList()
        {
            InitializeComponent();
            mSortManager = new ListViewSortManager(lstView, new Type[] 
            { typeof(PACKETPARSERMAX20.ListViewTextSort), 
                typeof(PACKETPARSERMAX20.ListViewTextSort),
                typeof(PACKETPARSERMAX20.ListViewDateSort), 
                typeof(PACKETPARSERMAX20.ListViewTextSort), 
                typeof(PACKETPARSERMAX20.ListViewInt32Sort), 
                typeof(PACKETPARSERMAX20.ListViewTextSort) });
        }

        private ListViewSortManager mSortManager = null;

        //private frmMain.DelegateProcessLogs ProcessLogs = null;
        private delegate DefinitionProcessor[] DelegateGetCheckedItems();
        private delegate void delegateUpdateLog(DefinitionProcessor definitionProcessor);

        public void Init(string[] pDirList)//, frmMain.DelegateProcessLogs pProcessLogs)
        {
            //ProcessLogs = pProcessLogs;

            lstView.Items.Clear();
            List<LogItem> tList = new List<LogItem>();

            foreach (string tDir in pDirList)
            {
                if (System.IO.Directory.Exists(tDir))
                {
                    string[] tFileList = System.IO.Directory.GetFiles(tDir, "*.sqlite", System.IO.SearchOption.AllDirectories);


                    foreach (string tFile in tFileList)
                    {
                        tList.Add(LoadItem(tFile));
                    }

                    tFileList = System.IO.Directory.GetFiles(tDir, "*.conv", System.IO.SearchOption.AllDirectories);

                    foreach (string tFile in tFileList)
                    {
                        tList.Add(LoadItem(tFile));
                    }
                }
            }

            var tSorted = (from tResult in tList.AsQueryable() orderby tResult.ClientBuild descending, tResult.LastWriteTime descending select tResult);

            foreach (LogItem titem in tSorted)
                AddItem(titem);

            lstView.Columns[0].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            lstView.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            lstView.Columns[2].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            lstView.Columns[3].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            lstView.Columns[4].Width = 100;//.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            lstView.Columns[5].Width = 100;//.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);

            //mSortManager.Sort(0, SortOrder.Descending);
        }


        public class LogItem
        {
            public string Name { get; set; }
            public DefinitionProcessor DefinitionProcessor { get; set; }
            public string Extension { get; set; }
            public DateTime LastWriteTime { get; set; }
            public string Length { get; set; }
            public string ClientBuild { get; set; }
        }
        private LogItem LoadItem(string file)
        {
            var reader = ReaderHelper.GetReaderForFile(file);
            var fileinfo = new System.IO.FileInfo(file);
            var processor = new DefinitionProcessor(reader, StaticObjects.eventManager, StaticObjects.opcodeFilter);

            var logitem = new LogItem() 
            {
                Name = processor.Reader.Name,
                ClientBuild = reader.ClientBuildName,
                DefinitionProcessor = processor,
                LastWriteTime = fileinfo.LastWriteTime,
                Extension = fileinfo.Extension,
                Length = fileinfo.Length.ToString() 
            };

            return logitem;
        }

        private void AddItem(LogItem pLogItem)
        {
            ListViewItem lvItem = lstView.Items.Add(pLogItem.Name);
            lvItem.Tag = pLogItem.DefinitionProcessor;

            lvItem.SubItems.Add(pLogItem.Extension);
            lvItem.SubItems.Add(pLogItem.LastWriteTime.ToString());
            lvItem.SubItems.Add(pLogItem.Length.ToString());
            lvItem.SubItems.Add("-1");
            lvItem.SubItems.Add(pLogItem.ClientBuild);
        }

        public DefinitionProcessor SelectedItem
        {
            get
            {
                if (lstView.SelectedItems.Count > 0)
                {
                    return (DefinitionProcessor)lstView.SelectedItems[0].Tag;
                }

                return null;
            }
        }

        public DefinitionProcessor[] CheckedItems
        {
            get
            {
                if (this.InvokeRequired)
                {
                    DelegateGetCheckedItems tdelegate = new DelegateGetCheckedItems(GetCheckedItems);
                    return (DefinitionProcessor[])this.Invoke(tdelegate);
                }
                else
                {
                    return GetCheckedItems();
                }
            }
        }

        public ListView.ListViewItemCollection GetListViewItemCollection()
        {

            return lstView.Items;


        }

        public DefinitionProcessor[] GetItems()
        {

            if (this.InvokeRequired)
            {
                DelegateGetCheckedItems tdelegate = new DelegateGetCheckedItems(GetItems);
                return (DefinitionProcessor[])this.Invoke(tdelegate);
            }
            else
            {

                DefinitionProcessor[] tReaderArray = new DefinitionProcessor[lstView.Items.Count];
                int i = 0;
                foreach (ListViewItem lvItem in lstView.Items)
                {
                    tReaderArray[i] = (DefinitionProcessor)lvItem.Tag;
                    //if (lvItem.SubItems[4].Text == "-1")
                    //{
                    //    lvItem.SubItems[4].Text = tReaderArray[i].Reader.Total.ToString();
                    //}
                    //if (lvItem.SubItems[5].Text == "-1")
                    //{
                    //    lvItem.SubItems[5].Text = tReaderArray[i].Reader.ClientBuild.ToString();
                    //}
                    i++;
                }

                return tReaderArray;

            }
        }

        private DefinitionProcessor[] GetCheckedItems()
        {
            if (lstView.CheckedItems.Count > 0)
            {
                DefinitionProcessor[] tReaderArray = new DefinitionProcessor[lstView.CheckedItems.Count];
                int i = 0;
                foreach (ListViewItem lvItem in lstView.CheckedItems)
                {
                    tReaderArray[i] = (DefinitionProcessor)lvItem.Tag;
                    lvItem.SubItems[4].Text = tReaderArray[i].Reader.TotalStored.ToString();
                    lvItem.SubItems[5].Text = tReaderArray[i].Reader.ClientBuild.ToString();

                    i++;
                }

                return tReaderArray;
            }

            return null;
        }

        public void UpdateLog(DefinitionProcessor definitionProcessor)
        {
            if (InvokeRequired)
            {
                this.Invoke(new delegateUpdateLog(UpdateLog), definitionProcessor);
            }
            else
            {
                foreach (ListViewItem lvItem in lstView.CheckedItems)
                {
                    if (definitionProcessor == lvItem.Tag)
                    {
                        lvItem.SubItems[4].Text = definitionProcessor.Reader.TotalStored.ToString();
                        break;
                    }
                }
            }
        }

        private void lstView_DoubleClick(object sender, EventArgs e)
        {
            //DefinitionProcessor tSelectedItem = SelectedItem;
            //if (tSelectedItem != null)
            //{
            //    ProcessLogs(new DefinitionProcessor[] { tSelectedItem });
            //}
        }

        private void mnuMainCopyName_Click(object sender, EventArgs e)
        {
            DefinitionProcessor tSelected = SelectedItem;

            if (tSelected != null)
            {
                Clipboard.Clear();
                Clipboard.SetText(tSelected.Reader.Name);
            }
        }

        private void mnuMainFindLog_Click(object sender, EventArgs e)
        {
            DefinitionProcessor tSelected = SelectedItem;

            if (tSelected != null)
            {

                //Option            Function
                //----------------------------------------------------------------------   
                ///n                Opens a new single-pane window for the default
                // selection. This is usually the root of the drive that
                // Windows is installed on. If the window is already
                // open, a duplicate opens.

                ///e                Opens Windows Explorer in its default view.

                ///root,<object>    Opens a window view of the specified object.

                ///select,<object>  Opens a window view with the specified folder, file,
                // or program selected.
                System.Diagnostics.Process.Start("explorer", "/e,/select,\"" + tSelected.Reader.FileName + "\"");
            }
        }

        private void mnuMainClear_Click(object sender, EventArgs e)
        {
            DefinitionProcessor tSelected = SelectedItem;

            if (tSelected != null)
            {
                tSelected.Reset();

            }
        }
    }
}